package com.example.controller.user;

import com.example.dto.business.UserBusinessDTO;
import com.example.dto.request.group.InsertGroup;
import com.example.dto.request.user.UserLoginRegisterRequestDTO;
import com.example.dto.request.user.UserLoginRegisterRequestDTO.NormalLoginGroup;
import com.example.exception.InsertException;
import com.example.exception.user.UserNotFoundException;
import com.example.exception.user.UnavailableUsernameException;
import com.example.pojo.User;
import com.example.response.ErrorStatus;
import com.example.response.ApiResult;
import com.example.service.user.UserAuthenticationService;
import com.example.vo.user.UserLoginRegisterRequestVO;
import com.example.service.user.UserLoginRegisterService;
import com.example.service.user.impl.UserAuthorizationServiceImpl;
import com.example.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author Lexin Huang
 */
@Api(tags = "用户登录注册模块")
@Slf4j
@RestController
public class UserLoginRegisterController {

    private final
    UserLoginRegisterService userLoginRegisterService;

    private final UserAuthorizationServiceImpl userAuthorizationService;

    private final UserAuthenticationService userAuthenticationService;


    public UserLoginRegisterController(UserLoginRegisterService userLoginRegisterService, UserAuthorizationServiceImpl userAuthorizationService, UserAuthenticationService userAuthenticationService) {
        this.userLoginRegisterService = userLoginRegisterService;
        this.userAuthorizationService = userAuthorizationService;
        this.userAuthenticationService = userAuthenticationService;
    }

    @PostMapping("/login")
    @ApiOperation("登录接口")
    public ApiResult<UserLoginRegisterRequestVO> login(@Validated(value = {NormalLoginGroup.class})
                                                       @RequestBody UserLoginRegisterRequestDTO request) {
        ApiResult<UserLoginRegisterRequestVO> response = new ApiResult<>();
        try {
            User user = userLoginRegisterService.normalLogin(request.getUsername(), request.getPassword());
            String token = userAuthorizationService.authorize(user);
            response.setSuccess(new UserLoginRegisterRequestVO(token,
                    new UserBusinessDTO(user)), "登录成功!");
        } catch (UserNotFoundException e) {
            log.info(e.getMessage());
            response.setError(ErrorStatus.MISMATCH);
        }
        return response;
    }

    @PostMapping("/token_login")
    @ApiOperation("免密登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header")
    })
    public ApiResult<UserLoginRegisterRequestVO> tokenLogin(@RequestHeader("token") String token) {
        ApiResult<UserLoginRegisterRequestVO> response = new ApiResult<>();
        User user = userAuthenticationService.login(token);
        response.setSuccess(new UserLoginRegisterRequestVO(token,
                new UserBusinessDTO(user)), "登录成功!");
        return response;
    }

    @PostMapping("/register")
    @ApiOperation("注册接口")
    public ApiResult<UserLoginRegisterRequestVO> register(@Validated(value = {InsertGroup.class})
                                                                   @RequestBody UserLoginRegisterRequestDTO request) {
        ApiResult<UserLoginRegisterRequestVO> response = new ApiResult<>();
        try {
            User user = userLoginRegisterService.register(request.getUsername(), request.getPassword(), request.getEmailAddress());
            String token = StringUtil.getUniqueCharSequence();
            userAuthorizationService.refreshUserTokenCache(token, user);
            response.setSuccess(new UserLoginRegisterRequestVO(token,
                    new UserBusinessDTO(user)), "注册成功!");
        } catch (UnavailableUsernameException | DuplicateKeyException e) {
            log.info(e.getMessage());
            response.setError(ErrorStatus.USERNAME_NOT_AVAILABLE);
        } catch (InsertException e) {
            log.info(e.getMessage());
            response.setError(ErrorStatus.SERVICE_NOT_AVAILABLE, e.getMessage());
        }
        return response;

    }

    @PostMapping("/logout")
    @ApiOperation("退出登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "用户令牌", required = true,
                    dataTypeClass = String.class, paramType = "header")
    })
    public ApiResult<ApiResult.ApiData> logout(@RequestHeader(value = "token", required = false) String token) {
        userAuthorizationService.logout(token);
        return ApiResult.buildNonDataSuccessResponse("注销成功!");
    }


}
